﻿#Использовать logos

Перем юТест;
Перем Лог;

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт
	
	юТест = ЮнитТестирование;
	
	ВсеТесты = Новый Массив;
	
	ВсеТесты.Добавить("ТестДолжен_ПолучитьПутьКOscript");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьРазделениеСтрокПриВыводе");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапроса");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапросаСтрокой");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапросаСтрокойВAnsi");
	
	ВсеТесты.Добавить("ТестДолжен_ПроверитьОбработкуПростогоФайла");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьОбработкуФайлаРазбитогоНаЧасти");
	
	Возврат ВсеТесты;
	
КонецФункции

Процедура ПередЗапускомТеста() Экспорт
	
	Лог = Логирование.ПолучитьЛог("oscript.tests.cgi");
	Лог.УстановитьУровень(УровниЛога.Информация);
	
КонецПроцедуры

Процедура ПослеЗапускаТеста() Экспорт
	Лог = Неопределено;
КонецПроцедуры

Процедура ТестДолжен_ПолучитьПутьКOscript() Экспорт
	
	Путь = Новый Файл(ПутьОСкрипт());
	
	юТест.ПроверитьИстину(Путь.Существует());
	
КонецПроцедуры

Функция СтрокаЗапускаОСкрипта(Знач ПутьКИсполняемомуМодулю)

	СИ = Новый СистемнаяИнформация;
	Если Найти(СИ.ВерсияОС, "Windows") > 0 Тогда
		Возврат """" + ПутьКИсполняемомуМодулю + """";
	КонецЕсли;

	Возврат "mono """ + ПутьКИСполняемомуМодулю + """";

КонецФункции

Функция ПолучитьВыводДляСкрипта(Знач Путь
	, Знач ТекстСкрипта
	, Знач ДанныеЗапроса = ""
	, Знач КодировкаДанных = Неопределено
	, Знач ЗапросРазбитНаЧасти = Ложь)

	ИмяФайлаОСкрипта = ПолучитьИмяВременногоФайла("os");

	Лог.Отладка("ТекстСкрипта <<" + Символы.ПС + ТекстСкрипта+Символы.ПС+">>");
	
	ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаОСкрипта);
	ЗаписьТекста.Записать(ТекстСкрипта);
	ЗаписьТекста.Закрыть();
	
	Возврат ЗапуститьФайлСкрипта(Путь, ИмяФайлаОСкрипта, ДанныеЗапроса, КодировкаДанных, ЗапросРазбитНаЧасти);
	
КонецФункции

Функция ЗапуститьФайлСкрипта(Знач Путь
	, Знач ИмяФайлаОСкрипта
	, Знач ДанныеЗапроса = ""
	, Знач КодировкаДанных = Неопределено
	, Знач ЗапросРазбитНаЧасти = Ложь)
	
	Перем ИмяФайла, СтрокаЗапуска;

	Если Не ПустаяСтрока(ДанныеЗапроса) Тогда
		Лог.Отладка("ДанныеЗапроса <<" + Символы.ПС + ДанныеЗапроса + Символы.ПС+">>");

		Если КодировкаДанных = Неопределено Тогда
			КодировкаДанных = КодировкаТекста.UTF8NoBOM;
		КонецЕсли;

		ИмяФайлаДанныхЗапроса = ПолучитьИмяВременногоФайла("txt");
		ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаДанныхЗапроса, КодировкаДанных);
		ЗаписьТекста.Записать(ДанныеЗапроса);
		ЗаписьТекста.Закрыть();

		Ф = Новый Файл(ИмяФайлаДанныхЗапроса);
		РазмерДанныхЗапроса = Строка(Ф.Размер()); // тут надо Формат

	КонецЕсли;
	
	ИмяФайлаВывода = ПолучитьИмяВременногоФайла("txt");

	СИ = Новый СистемнаяИнформация;
	Если Найти(СИ.ВерсияОС, "Windows") > 0 Тогда
	
		ИмяФайлаСистемногоСкриптаЗапуска = ПолучитьИмяВременногоФайла("cmd");
		ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаСистемногоСкриптаЗапуска, КодировкаТекста.Oem);
		ЗаписьТекста.ЗаписатьСтроку("@echo off");
		ЗаписьТекста.ЗаписатьСтроку("set SCRIPT_FILENAME=" + ИмяФайлаОСкрипта);
		ЗаписьТекста.ЗаписатьСтроку("set CONTENT_LENGTH=" + РазмерДанныхЗапроса);
		
		Если ЗапросРазбитНаЧасти Тогда
			ЗаписьТекста.ЗаписатьСтроку("set CONTENT_TYPE=multipart/form-data;boundary=boundary");
		КонецЕсли;
		
		ЗаписьТекста.ЗаписатьСтроку(СтрокаЗапускаОСкрипта(Путь) + " -cgi"
			+ ?(ПустаяСтрока(ДанныеЗапроса), "", " < " + ИмяФайлаДанныхЗапроса)
			+ " > " + ИмяФайлаВывода
		);
		ЗаписьТекста.Закрыть();

		СтрокаЗапуска = ИмяФайлаСистемногоСкриптаЗапуска;

	Иначе
	
		ИмяФайлаСистемногоСкриптаЗапуска = ПолучитьИмяВременногоФайла("sh");
		ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаСистемногоСкриптаЗапуска,,,, Символы.ПС);
		ЗаписьТекста.ЗаписатьСтроку("bash -s <<<CALLEOF");
		ЗаписьТекста.ЗаписатьСтроку("SCRIPT_FILENAME=" + ИмяФайлаОСкрипта + " " 
			+ ?(ПустаяСтрока(ДанныеЗапроса), "", " CONTENT_LENGTH=" + РазмерДанныхЗапроса) + " "
			+ ?(ЗапросРазбитНаЧасти, "CONTENT_TYPE=""multipart/form-data;boundary=boundary"" ", "")
			+ СтрокаЗапускаОСкрипта(Путь) + " -cgi"
			+ ?(ПустаяСтрока(ДанныеЗапроса), "", " < " + ИмяФайлаДанныхЗапроса)
			+ " > " + ИмяФайлаВывода
		);
		ЗаписьТекста.ЗаписатьСтроку("CALLEOF");
		ЗаписьТекста.Закрыть();

		СтрокаЗапуска = "bash " + ИмяФайлаСистемногоСкриптаЗапуска;

	КонецЕсли;
	
	Лог.Отладка("СтрокаЗапуска " + СтрокаЗапуска);
	
	Процесс = СоздатьПроцесс(СтрокаЗапуска,,Истина);
	Процесс.Запустить();

	Процесс.ОжидатьЗавершения();
	
	Текст = Новый ТекстовыйДокумент;
	Текст.Прочитать(ИмяФайлаВывода, КодировкаТекста.UTF8);
	
	// Стр = Текст.ПолучитьТекст();
	Стр = НормализоватьПереводыСтрок(Текст.ПолучитьТекст());
	Лог.Отладка("Текст файла вывода <<" + Символы.ПС + Стр + Символы.ПС+">>");

	Возврат Стр;

КонецФункции

Процедура ТестДолжен_ПроверитьРазделениеСтрокПриВыводе() Экспорт
	// Лог.УстановитьУровень(УровниЛога.Отладка);
	
	Путь = ПутьОСкрипт();
	Лог.Отладка("ПутьОСкрипт " + Путь);

	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;
	
	ПроверкаПереводаСтрок = ПолучитьВыводДляСкрипта(Путь,
		"Сообщить(""Строка1""); Сообщить(""Строка2"");"
	);
	
	ОжидаемыйВывод = ОжидаемыеЗаголовки +
		"Строка1
		|Строка2
		|"
	;
	юТест.ПроверитьРавенство(ОжидаемыйВывод, ПроверкаПереводаСтрок);
	
КонецПроцедуры

Процедура ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапроса() Экспорт

	Путь = ПутьОСкрипт();

	ПроверочнаяСтрока = "ПроверочнаяСтрока
		|на несколько строк с невероятным символом " + Символ(12500)
	;
	Данные = ПолучитьВыводДляСкрипта(Путь,
		"ИмяФайла = ПолучитьИмяВременногоФайла(""txt"");
		|ВебЗапрос.ПолучитьТелоКакДвоичныеДанные().Записать(ИмяФайла);
		|Текст = Новый ТекстовыйДокумент;
		|Текст.Прочитать(ИмяФайла, ""UTF-8"");
		|Сообщить(Текст.ПолучитьТекст());
		|",
		ПроверочнаяСтрока
	);

	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;

	ПроверочнаяСтрока = ОжидаемыеЗаголовки + ПроверочнаяСтрока;

	Данные = СокрЛП(Данные);
	ПроверочнаяСтрока = СокрЛП(ПроверочнаяСтрока);

	юТест.ПроверитьРавенство(Данные, ПроверочнаяСтрока);

КонецПроцедуры



Процедура ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапросаСтрокой() Экспорт

	Путь = ПутьОСкрипт();

	ПроверочнаяСтрока = "ПроверочнаяСтрока
		|на несколько строк с невероятным символом " + Символ(12500)
	;
	Данные = ПолучитьВыводДляСкрипта(Путь,
		"
		|Сообщить(ВебЗапрос.ПолучитьТелоКакСтроку());
		|",
		ПроверочнаяСтрока
	);

	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;

	ПроверочнаяСтрока = ОжидаемыеЗаголовки + ПроверочнаяСтрока;

	Данные = СокрЛП(Данные);
	ПроверочнаяСтрока = СокрЛП(ПроверочнаяСтрока);

	юТест.ПроверитьРавенство(Данные, ПроверочнаяСтрока);

КонецПроцедуры

Процедура ТестДолжен_ПроверитьПолучениеСырыхДанныхЗапросаСтрокойВAnsi() Экспорт

	Путь = ПутьОСкрипт();

	ПроверочнаяСтрока = "ПроверочнаяСтрока
		|на несколько строк без utf"
	;
	Данные = ПолучитьВыводДляСкрипта(Путь,
		"
		|Сообщить(ВебЗапрос.ПолучитьТелоКакСтроку(КодировкаТекста.Ansi));
		|",
		ПроверочнаяСтрока, КодировкаТекста.Ansi
	);

	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;

	ПроверочнаяСтрока = ОжидаемыеЗаголовки + ПроверочнаяСтрока;

	Данные = СокрЛП(Данные);
	ПроверочнаяСтрока = СокрЛП(ПроверочнаяСтрока);

	юТест.ПроверитьРавенство(Данные, ПроверочнаяСтрока);

КонецПроцедуры


Функция ТекущийПуть(Знач ОтносительныйПуть)
	Возврат ОбъединитьПути(ТекущийСценарий().Каталог, ОтносительныйПуть);
КонецФункции

Процедура ТестДолжен_ПроверитьОбработкуПростогоФайла() Экспорт

	ФайлДанных = 
		"3
		|2
		|6
		|8
		|4
		|1"
	;
	
	Данные = ЗапуститьФайлСкрипта(ПутьОСкрипт()
		, ТекущийПуть("cgi/sortrawfile.os")
		, ФайлДанных
		,
		, Ложь // Не разбит на части
	);
	
	ПроверочнаяСтрока = "1
		|2
		|3
		|4
		|6
		|8
		|"
	;
	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;

	ПроверочнаяСтрока = ОжидаемыеЗаголовки + ПроверочнаяСтрока;

	Данные = СокрЛП(Данные);
	ПроверочнаяСтрока = СокрЛП(ПроверочнаяСтрока);

	юТест.ПроверитьРавенство(Данные, ПроверочнаяСтрока);
КонецПроцедуры

Процедура ТестДолжен_ПроверитьОбработкуФайлаРазбитогоНаЧасти() Экспорт

	ФайлДанных = "--boundary
		|Content-Disposition: form-data; name=""text1""
		|
		// Ненужные данные
		|xcxcxcxcxcxcxcxc
		
		// Файл, разбитый на две части
		|--boundary
		|Content-Disposition: form-data; name=""RequestedFile""; filename=""File_from_my_PC.txt""
		|Content-Type: text/plain
		|
		|3
		|2
		|6
		|8
		|
		|--boundary
		|Content-Disposition: form-data; name=""RequestedFile""; filename=""File_from_my_PC.txt""
		|Content-Type: text/plain
		|
		|4
		|1
		|--boundary--"
	;

	Данные = ЗапуститьФайлСкрипта(ПутьОСкрипт()
		, ТекущийПуть("cgi/sortfile.os")
		, ФайлДанных
		,
		, Истина // Разбит на части
	);
	
	ПроверочнаяСтрока = "1
		|2
		|3
		|4
		|6
		|8
		|"
	;
	ОжидаемыеЗаголовки = 
		"Content-type: text/html
		|Content-encoding: utf-8
		|
		|"
	;

	ПроверочнаяСтрока = ОжидаемыеЗаголовки + ПроверочнаяСтрока;

	Данные = СокрЛП(Данные);
	ПроверочнаяСтрока = СокрЛП(ПроверочнаяСтрока);

	юТест.ПроверитьРавенство(Данные, ПроверочнаяСтрока);

КонецПроцедуры

Функция ПутьОСкрипт()
	Возврат КаталогПрограммы() + "/oscript.exe";
КонецФункции

Функция НормализоватьПереводыСтрок(Знач ИсходнаяСтрока)
	Возврат СтрЗаменить(ИсходнаяСтрока, Символы.ВК, "");
КонецФункции

